package com.cynteka.cyfoman.core.collection;

import com.cynteka.cyfoman.core.ValueObject;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * User: Sergey
 * Date: 05.08.11
 * Time: 20:36
 */
public class ExcelCollection extends BaseCollection<ValueObject> {
    public static final String FILE_PARAM = "file";
    private static Logger logger = Logger.getLogger(ExcelCollection.class.getName());
    private String sheetName;

    public boolean isSkipEmpty() {
        return skipEmpty;
    }

    public void setSkipEmpty(boolean skipEmpty) {
        this.skipEmpty = skipEmpty;
    }

    private boolean skipEmpty = false;
    private int sheetIdx;
    private int startRow = 0;
    private int endRow = Integer.MAX_VALUE;
    private int startColumn = -1;
    private int endColumn = Integer.MAX_VALUE;
    private int rowNumber = -1;
    private List<String> columnNames;
    private int numberTitleRows = 0;

    public int getNumberTitleRows() {
        return numberTitleRows;
    }

    public void setNumberTitleRows(int numberTitleRows) {
        this.numberTitleRows = numberTitleRows;
    }

    private File excelFile;

    public File getExcelFile() {
        return excelFile;
    }

    public void setExcelFile(File excelFile) {
        this.excelFile = excelFile;
    }

    public String getSheetName() {
        return sheetName;
    }

    public void setSheetName(String sheetName) {
        this.sheetName = sheetName;
    }

    public int getSheetIdx() {
        return sheetIdx;
    }

    public void setSheetIdx(int sheetIdx) {
        this.sheetIdx = sheetIdx;
    }

    public int getStartRow() {
        return startRow;
    }

    public void setStartRow(int startRow) {
        this.startRow = startRow;
    }

    public int getStartColumn() {
        return startColumn;
    }

    public void setStartColumn(int startColumn) {
        this.startColumn = startColumn;
    }

    public int getRowNumber() {
        return rowNumber;
    }

    public void setRowNumber(int rowNumber) {
        this.rowNumber = rowNumber;
    }

    public List<String> getColumnNames() {
        return columnNames;
    }

    public void setColumnNames(List<String> columnNames) {
        this.columnNames = columnNames;
    }

    public ExcelCollection(String id) {
        super(id);
    }

    @Override
    public Collection<ValueObject> getItems(Map<String, Object> params) {
        Collection<ValueObject> res = new ArrayList<ValueObject>();
        Object value = excelFile != null ? excelFile : params.get(FILE_PARAM);
        if (value instanceof File) {
            try {
                File file = (File) value;
                InputStream in = new FileInputStream(file);
                HSSFWorkbook wb = new HSSFWorkbook(in);
                Sheet sheet;
                if (sheetName != null)
                    sheet = wb.getSheet(sheetName);
                else
                    sheet = wb.getSheetAt(sheetIdx);

                int rowFound = 0;
                for (Row row : sheet) {
                    if(row.getRowNum() > endRow)
                        break;
                    if (row.getRowNum() >= startRow) {
                        ValueObject valueObject = processRow(row);

                        if (valueObject != null) {
                            if (rowFound > numberTitleRows)
                                res.add(valueObject);
                            rowFound++;
                        }
                    }
                }

            } catch (IOException ioe) {
                logger.log(Level.SEVERE, "Can not read file", ioe);
            }

        }
        return res;
    }

    protected ValueObject processRow(Row row) {
        ValueObject<String, Object> valueObject = new ValueObject<String, Object>();
        boolean empty = true;
        if (startColumn < 0) {
            int idx = 0;
            for (Cell cell : row) {
                if(cell.getColumnIndex() > endColumn)
                    break;
                if(cell.getColumnIndex() >= startColumn) {
                    if (idx >= columnNames.size())
                        break;
                    String columnName = columnNames.get(idx);
                    if (columnName != null && columnName.trim().length() > 0) {
                        String cellValue = cell.getStringCellValue();
                        valueObject.setParam(columnName, cellValue);
                        if (cellValue != null && cellValue.trim().length() > 0)
                            empty = false;
                    }
                    idx++;
                }
            }
        }
        if (isSkipEmpty() && empty)
            return null;
        return valueObject;
    }
}
